home *** CD-ROM | disk | FTP | other *** search
/ Super PC 34 / Super PC 34 (Shareware).iso / spc / UTIL / DJGPP2 / CONTRIB / ZLIB_PC.ZIP / zlib_pc / zfgetc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-06-20  |  6.0 KB  |  285 lines

  1. #include "zdef.h"
  2.  
  3. #ifdef __STDC__
  4. static void     decompress_more(register ZFILE *z);
  5. static long     getcode(register ZFILE *z);
  6. #else
  7. static void     decompress_more();
  8. static long     getcode();
  9. #endif
  10.  
  11. #define CR        0x0D
  12. #define LF        0x0A
  13.  
  14. /*------------------------------*/
  15. /*    zfgetc            */
  16. /*------------------------------*/
  17. #ifndef __STDC__
  18. int zfgetc (z)
  19. ZFILE *z;
  20. #else
  21. int zfgetc (ZFILE *z)
  22. #endif
  23. {
  24.     int     c;
  25.  
  26.     /* 
  27.      *   If buffer empty, and not end-of-file, call decompress_more();
  28.      *   return next in buffer.  
  29.      */
  30. again:
  31.     if ((z->flags & NOT_COMPRESSED) != 0)
  32.     {
  33.         if ((c = z->c1) >= 0)
  34.         {
  35.             z->c1 = z->c2;
  36.             z->c2 = EOF;
  37.  
  38.             return ((int) c);
  39.         }
  40. again2:
  41.         c = fgetc (z->file);
  42. #if defined(ALCYON)
  43.         /*
  44.          *   see note below...
  45.          */
  46.         if (c == CR)
  47.             goto again2;
  48. #endif
  49.         return ((int) c);
  50.     }
  51.     if ((z->bufget == z->bufput) && (!z->zeof))
  52.     {
  53.         decompress_more (z);
  54.     }
  55.     z->zeof = (z->bufput == z->bufget);
  56.     if (z->zeof)
  57.     {
  58.         if ((z->flags & ALLOCATED) != 0)
  59.         {
  60. #ifdef MSDOS
  61.             hfree (z->tab_suffixof);
  62.             hfree (z->tab_prefixof);
  63. #else
  64.             free (z->tab_suffixof);
  65.             free (z->tab_prefixof);
  66. #endif
  67.             z->flags &= (~ALLOCATED);
  68.         }
  69.         return ((int) EOF);
  70.     }
  71.     c = z->buff[z->bufget];
  72.     z->bufget++;
  73.  
  74. #ifdef MONITOR_CRLF
  75.     if (c == CR)
  76.         fprintf (stderr, "\n*** CR IN INPUT ***\n");
  77.     if (c == LF)
  78.         fprintf (stderr, "\n*** LF IN INPUT ***\n");
  79. #endif
  80.  
  81. #if defined(ALCYON)
  82.     /*
  83.      *   at least with alcyon, fputc will write a cr-nl if c is nl so
  84.      *   skip past the cr we read. other libraries may or may not have
  85.      *   this problem...
  86.      */
  87.     if (c == CR)
  88.         goto again;
  89. #endif
  90.  
  91.     return ((int) c);
  92. }
  93.  
  94.  
  95.  
  96. /*------------------------------*/
  97. /*    decompress_more        */
  98. /*------------------------------*/
  99. #ifndef __STDC__
  100. static void decompress_more (z)
  101. register ZFILE *z;
  102. #else
  103. static void decompress_more (register ZFILE *z)
  104. #endif
  105. {
  106.     z->bufput = 0;
  107.     z->bufget = 0;
  108.  
  109.     if (z->init != 0)
  110.         goto resume;
  111.  
  112.     z->init   = 1;
  113.     z->offset = 0;
  114.     z->size   = 0;
  115.  
  116. #ifdef MSDOS
  117.     z->tab_suffixof =
  118.         (unsigned char PC_HUGE *) halloc (HSIZE, sizeof (unsigned char));
  119.     z->tab_prefixof =
  120.         (long PC_HUGE *) halloc (HSIZE, sizeof (long));
  121. #else
  122.     z->tab_suffixof =
  123.         (unsigned char *) malloc ((size_t) HSIZE * sizeof (unsigned char));
  124.     z->tab_prefixof = (long *) malloc ((size_t) HSIZE * sizeof (long));
  125. #endif
  126.     z->flags |= ALLOCATED;
  127.  
  128.     z->n_bits  = INIT_BITS;
  129.     z->maxcode = ((1L << (z->n_bits)) - 1L);
  130.     for (z->code = 255L; z->code >= 0L; z->code--)
  131.     {
  132.         z->tab_prefixof[z->code] = 0L;
  133.         z->tab_suffixof[z->code] = (unsigned char) z->code;
  134.     }
  135.     z->free_ent = ((z->block_compress) ? FIRST : 256L);
  136.  
  137.     z->finchar = z->oldcode = getcode (z);
  138.     if (z->oldcode == -1L)
  139.         return;            /* EOF already? */
  140.     if (z->finchar < 0L || z->finchar >= 256L)
  141.         fprintf (stderr, "****\n");
  142.     z->buff[z->bufput] = (char) (z->finchar & 0xff);
  143.     z->bufput++;
  144.  
  145.     z->stackp = 1L << Z_BITS;    /* The 1L is for DOS huge arrays */
  146.  
  147.     while ((z->code = getcode (z)) != EOF)
  148.     {
  149.         if ((z->code == CLEAR) && z->block_compress)
  150.         {
  151.             for (z->code = 255; z->code >= 0; z->code--)
  152.                 z->tab_prefixof[z->code] = 0;
  153.             z->clear_flg = 1;
  154.             z->free_ent  = FIRST - 1;
  155.             if ((z->code = getcode (z)) == EOF)
  156.                 break;    /* O, untimely death! */
  157.         }            /* if */
  158.         z->incode = z->code;
  159.         if (z->code >= z->free_ent)
  160.         {
  161.             z->tab_suffixof[z->stackp] = (unsigned char)z->finchar;
  162.             z->stackp                 += 1L;
  163.             z->code                    = z->oldcode;
  164.         }
  165.         while (z->code >= 256L)
  166.         {
  167.             z->tab_suffixof[z->stackp] = z->tab_suffixof[z->code];
  168.             z->stackp                 += 1L;
  169.             z->code                    = z->tab_prefixof[z->code];
  170.         }
  171.         z->finchar                 = z->tab_suffixof[z->code];
  172.         z->tab_suffixof[z->stackp] = (unsigned char) z->finchar;
  173.         z->stackp                 += 1L;
  174.         do
  175.         {
  176.             long    tmp;
  177.  
  178.             z->stackp           -= 1L;
  179.             tmp                  = z->tab_suffixof[z->stackp];
  180.             z->buff[z->bufput++] = (unsigned char) (tmp & 255L);
  181.             if (z->bufput == z->bufend)
  182.             {
  183.                 /*
  184.                  *   Logically a setjmp/longjump, but this
  185.                  *   is more portable
  186.                  */
  187.                 return;
  188.  
  189.                 /*
  190.                  *   jumped to here -- is jumping into a
  191.                  *   loop safe?
  192.                  *   - or should I use jumps for the loop too?
  193.                  */
  194. resume:                ;
  195.             }        /* if */
  196.  
  197.         } while (z->stackp > (1L << Z_BITS));
  198.         /* ^ This is why I changed stackp from a pointer. */
  199.         /* Pointer comparisons can be dubious...          */
  200.  
  201.         if ((z->code = z->free_ent) < (1L << z->maxbits))
  202.         {
  203.             z->tab_prefixof[z->code] = z->oldcode;
  204.             z->tab_suffixof[z->code] = (unsigned char) z->finchar;
  205.             z->free_ent              = z->code + 1;
  206.         }
  207.         z->oldcode = z->incode;
  208.     }                /* while */
  209. }
  210.  
  211. static unsigned char    rmask[9] =
  212. {
  213.     0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff
  214. };
  215.  
  216.  
  217. /*------------------------------*/
  218. /*    getcode            */
  219. /*------------------------------*/
  220. #ifndef __STDC__
  221. static long getcode (z)
  222. register ZFILE *z;
  223. #else
  224. static long getcode (register ZFILE *z)
  225. #endif
  226. {                    /* Should be int!!! */
  227.     register long   code;
  228.     register long   r_off,
  229.                     bits;
  230.     register int    bp;
  231.  
  232.     bp = 0;
  233.     if (z->clear_flg != 0 || z->offset >= z->size
  234.     || z->free_ent > z->maxcode)
  235.     {
  236.         if (z->free_ent > z->maxcode)
  237.         {
  238.             z->n_bits++;
  239.             if (z->n_bits == z->maxbits)
  240.             {
  241.                 z->maxcode = (1L << z->maxbits);
  242.                 /* won't get any bigger now */
  243.             }
  244.             else
  245.             {
  246.                 z->maxcode = ((1L << (z->n_bits)) - 1L);
  247.             }
  248.         }
  249.         if (z->clear_flg != 0)
  250.         {
  251.             z->n_bits    = INIT_BITS;
  252.             z->maxcode   = ((1L << (z->n_bits)) - 1L);
  253.             z->clear_flg = 0;
  254.         }
  255.         z->size = fread (z->buf, 1, (size_t) z->n_bits, z->file);
  256.         if (z->size <= 0)
  257.         {
  258.             fclose (z->file);
  259.             return ((long) EOF);    /* end of file */
  260.         }
  261.         z->offset = 0;
  262.         z->size   = (z->size << 3) - (z->n_bits - 1);
  263.     }
  264.     r_off = z->offset;
  265.     bits  = z->n_bits;
  266.     bp    = bp + ((int) r_off >> 3);
  267.     r_off = r_off & 7;
  268.     code  = ((long) z->buf[bp++] >> r_off);
  269.     bits  = bits - 8 + r_off;
  270.     r_off = 8 - r_off;        /* now, offset into code word */
  271.     if (bits >= 8)
  272.     {
  273.         code  = code | ((long) z->buf[bp++] << r_off);
  274.         r_off = r_off + 8;
  275.         bits  = bits - 8;
  276.     }
  277.     code = code
  278.         | ((long)((long)(z->buf[bp]) & (long)rmask[bits]) << (long)r_off);
  279.     z->offset = z->offset + z->n_bits;
  280.  
  281.     return ((long) code);
  282. }
  283.  
  284.  
  285.